
# 从 qtpy 库导入 QtCore 和 QtGui 模块，不过 QtGui 未使用，后续可移除
from qtpy import QtCore, QtGui
# 从 qtpy.QtWidgets 模块导入 QGraphicsWidget 类，用于创建图形化的小部件
from qtpy.QtWidgets import QGraphicsWidget
# 从 qtpy.QtWidgets 模块导入 QSizePolicy 类，用于设置小部件的大小策略
from qtpy.QtWidgets import QSizePolicy
# 从 qtpy.QtSvgWidgets 模块导入 QGraphicsSvgItem 类，用于在图形场景中显示 SVG 图标
from qtpy.QtSvgWidgets import QGraphicsSvgItem

class NodeActionButtonBase(QGraphicsWidget):
    """
    所有节点操作按钮的基类。

    默认情况下，它会调用操作的 `triggered` 信号。拥有一个默认的 10x10 的 SVG 图标。
    """

    def __init__(self, svgFilePath, action, uiNode):
        """
        初始化节点操作按钮基类。

        :param svgFilePath: SVG 图标的文件路径，用于显示按钮图标
        :param action: 与按钮关联的操作，按钮点击时会触发该操作的 `triggered` 信号
        :param uiNode: 按钮所属的 UI 节点
        """
        # 调用父类 QGraphicsWidget 的构造函数
        super(NodeActionButtonBase, self).__init__(uiNode)
        # 设置按钮接受悬停事件
        self.setAcceptHoverEvents(True)
        # 设置按钮的焦点策略为强焦点，即可以通过鼠标点击和键盘快捷键获得焦点
        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        # 设置当前对象为图形项
        self.setGraphicsItem(self)
        # 设置按钮的大小策略为最大化
        self.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum))
        # 保存与按钮关联的操作
        self.action = action
        # 创建一个 QGraphicsSvgItem 实例，用于显示指定路径的 SVG 图标
        self.svgIcon = QGraphicsSvgItem(svgFilePath, self)
        # 设置按钮的工具提示为关联操作的工具提示
        self.setToolTip(self.action.toolTip())
        # 标记按钮是否处于悬停状态，初始为 False
        self.hovered = False
        # 将当前按钮添加到所属 UI 节点的操作按钮集合中
        uiNode._actionButtons.add(self)

    def hoverEnterEvent(self, event):
        """
        处理鼠标进入按钮区域的事件。

        :param event: 鼠标进入事件对象
        """
        # 标记按钮处于悬停状态
        self.hovered = True
        # 更新按钮的显示
        self.update()

    def hoverLeaveEvent(self, event):
        """
        处理鼠标离开按钮区域的事件。

        :param event: 鼠标离开事件对象
        """
        # 标记按钮不处于悬停状态
        self.hovered = False
        # 更新按钮的显示
        self.update()

    def mousePressEvent(self, event):
        """
        处理鼠标按下按钮的事件。

        :param event: 鼠标按下事件对象
        """
        # 如果按钮所属的父项被选中，则取消其选中状态
        if self.parentItem().isSelected():
            self.parentItem().setSelected(False)

        # 如果关联的操作存在且按钮拥有焦点，则触发操作的 `triggered` 信号，并清除按钮的焦点
        if self.action is not None and self.hasFocus():
            self.action.triggered.emit()
            self.clearFocus()

    def setGeometry(self, rect):
        """
        设置按钮的几何形状。

        :param rect: 用于设置按钮几何形状的矩形对象
        """
        # 准备几何形状的更改
        self.prepareGeometryChange()
        # 调用父类的 setGeometry 方法设置几何形状，此处父类指定可能有误，后续可检查
        super(QGraphicsWidget, self).setGeometry(rect)
        # 设置按钮的位置为矩形的左上角
        self.setPos(rect.topLeft())

    def sizeHint(self, which, constraint):
        """
        返回按钮的建议大小。

        :param which: 用于指定请求哪种类型的大小提示
        :param constraint: 对大小的约束条件
        :return: 按钮的建议大小，为 QtCore.QSizeF 类型的对象，大小为 10x10
        """
        return QtCore.QSizeF(10, 10)